


// 校验单元格配置格式
interface RegExpValidatorConfItem {
  key: string;            // 关键key
  type: RegExpType | RegExpType[];   // 校验内置类型
  name: string;           // 校验项名称
  require?: boolean;      // 是否允许为空 value值
}

// 校验单元格式
interface RegExpValidatorItem extends RegExpValidatorConfItem {
  value: any;         // 待校验值
}

// 校验失败单元
interface RegExpValidatorErrorItem extends RegExpValidatorItem {
  msg: string;
}

// 校验返回格式
interface RegExpValidatorErrorResponse {
  validPassState: boolean;
  validErrors: RegExpValidatorErrorItem[];
}

// 校验配置
interface RegExpValidatorInter {
  [x: string]: RegExpValidatorItem;
}

// 参数
interface RegExpValidatorOptions {
  regConfig: RegExpValidatorConfItem[];
}

export enum RegExpType {
  CN,                   // 中文
  EN,                   // 英文字母
  EN_NUMBER,            // 任意英文+数字
  DECIMAL,              // 小数浮点数类型
  INTEGER,              // 整数类型 - 正负都可以
  POSITIVE_INTEGER,     // 整数类型 - 正数
  UP_ZERO_INTEGER,      // 0+正数 (<=0)
  UP_ONE_INTEGER,       // 1+正数 (<=1)
  NUMBER,               // 数字类型
  EMAIL,                // 电子邮箱
  PHONE,                // 手机 18165221849
  TEL,                  // 电话 0731-5632575
  PHONE_TEL,            // 手机 + 电话
  POSTCODE,             // 邮政编码
  HTTP,                 // http (支持 - :post,www,ip,http,https)
  IP,                   // ip地址
  IDENTITY_CARD         // 身份证
}


export default class RegExpValidator {

  private validPassState = true;                        // 最终的验证状态
  private regConfig: RegExpValidatorInter = {};         // 存储的配置校验 - 全量
  private validExcePool: RegExpValidatorItem[] = [];    // 本次执行 - 需要校验的组 （从 总仓regConfig 提取到 本次validExcePool）
  private validErrors: RegExpValidatorErrorItem[] = [];     // 错误集合

  constructor(options: RegExpValidatorOptions) {
    this.setOptions(options);
  }

  // 设置配置内容
  setOptions(options: RegExpValidatorOptions) {
    if (options) {
      const { regConfig } = options;
      
      if (regConfig) {
        let jsonConf: RegExpValidatorInter | any = {};
        regConfig.forEach(item => {
          jsonConf[item.key] = item;
        });
        this.regConfig = jsonConf;
      }
    }
  }

  // 执行
  exceValid = (formObj: { [x: string]: any; }): RegExpValidatorErrorResponse | never => {
    try {

      this.validPassState = true;

      let pools: RegExpValidatorItem[] = [];

      Object.keys(formObj).forEach(ikey => {
        let itemConf = this.regConfig[ikey];
        if (itemConf) {
          itemConf['value'] = formObj[ikey];
          pools.push(itemConf);
        }
      });

      this.validExcePool = pools;
      this.inlayVerify();

      return {
        validPassState: this.validPassState,
        validErrors: this.validErrors
      }
    } catch(err) {
      console.log('Bamboo-RegExpValidator: ', err);
      throw Error(err);
    }
  }

  // 非空则校验
  inlayVerify = (_valids?: RegExpValidatorItem[]) => {

    let valids = _valids || this.validExcePool;

    valids.forEach((item, index) => {

      /* if (typeof item.value === 'undefined') {
        throw Error('[lyq:Error at REGEXPverify.js] regexp error, the item not find [value]');
      } */

      if (
        !item.require
      ) {
        // 必填情况
        if (!this.notEmpty(item)) {
          this.validPassState = false;
        } else {
          if (item.type && Array.isArray(item.type)) {

          } else this._testRegExp(item);
        }
      } else if (item.require) {
        // 允许不填, 一旦有值则对应类型验证
        if (this.notEmpty(item)) {
          if (item.type && Array.isArray(item.type)) {

          } else this._testRegExp(item);
        }
      }
    });

    return this.validPassState;
  }

  // 正则校验
  _testRegExp (item: RegExpValidatorItem) {
    if (item.type !== undefined) {
      let reg, text;

      if (item.type === RegExpType.CN) {               // 中文
        reg = /^[\u0391-\uFFE5]+$/;
        text ='仅允许中文汉字';
      } else if (item.type === RegExpType.EN) {        // 英文字母
        reg = /^[a-zA-Z]+$/;
        text ='仅允许英文字母';
      } else if (item.type === RegExpType.EN_NUMBER) { // 任意英文+数字
        reg = /^[a-zA-Z0-9]+$/;
        text ='仅允许英文及数字';
      } else if (item.type === RegExpType.DECIMAL) {   // 小数浮点数类型
        reg = /^\d+(\.\d+)?$/;
        text ='必须是小数';
      } else if (item.type === RegExpType.INTEGER) {   // 整数类型 - 正负都可以
        reg = /^-?[1-9]\d+$/;
        text ='必须是整数';
      } else if (item.type === RegExpType.POSITIVE_INTEGER) {  // 整数类型 - 正数
        reg = /^[0-9]*[1-9][0-9]*$/;
        text ='必须是正整数';
      } else if (item.type === RegExpType.UP_ZERO_INTEGER) {  // 0+正数
        reg = /^(0|\+?[1-9][0-9]*)$/;
        text ='必须是大于等于0的整数';
      } else if (item.type === RegExpType.UP_ONE_INTEGER) {   // 1+正数
        reg = /^(1|\+?[1-9][0-9]*)$/;
        text ='必须是大于等于1的整数';
      } else if (item.type === RegExpType.NUMBER) {       // 数字类型
        reg = /^-?[0-9]\d+$/;
        text ='必须是数字';
      } else if (item.type === RegExpType.EMAIL) {        // 邮箱
        reg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/;
        text ='邮箱格式错误';
      } else if (item.type === RegExpType.PHONE) {        // 手机 18165221849
        reg = /^1\d{10}$/;
        text ='必须是手机号码';
      } else if (item.type === RegExpType.TEL) {          // 电话 0731-5632575
        reg = /^0\d{2,3}-?\d{7,8}$/;
        text ='必须是电话号码';
      } else if (item.type === RegExpType.PHONE_TEL) {    // 手机 + 电话
        reg = /^1\d{10}$|^0\d{2,3}-?\d{7,8}$/;
        text ='必须是手机或电话号码';
      } else if (item.type === RegExpType.POSTCODE) {     // 邮政编码
        reg = /^\d{6}$/;
        text ='必须是6位数字';
      } else if (item.type === RegExpType.HTTP) {         // http (支持 - :post,www,ip,http,https)
        reg = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/;
        text ='必须是正确url地址';
      } else if (item.type === RegExpType.IP) {           // ip地址
        reg = /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
        text ='必须是正确ip格式';
      } else if (item.type === RegExpType.IDENTITY_CARD) {  // 身份证
        //reg = /\d{18}|\d{15}/;
        reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;   // 15位 | 18位 | 17+X
        text ='必须是正确身份证';
      }

      if (!reg || !reg.test(item.value)) {      // item 验证不通过

        this.validPassState = false;

        let iError: RegExpValidatorErrorItem = {
          ...item,
          msg: text || ''
        };

        this.validErrors.push(iError);
      }
    }
  }

  // 判断当前值是否为空
  private notEmpty = (item: RegExpValidatorItem) => {  // 必填

    if (!item.value || item.value.toString().trim() === '') {
      /* Message({
        type: 'error',
        message: item.name + '不能为空!'
      }) */
      return false;
    }
    return true;
  }

}